<?php
/**
 * 易优CMS
 * ============================================================================
 * 版权所有 2016-2028 海口快推科技有限公司，并保留所有权利。
 * 网站地址: http://www.eyoucms.com
 * ----------------------------------------------------------------------------
 * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
 * ============================================================================
 * Author: 陈风任 <491085389@qq.com>
 * Date: 2019-1-7
 */

namespace app\common\model;

use think\Db;
use think\Cache;
use think\Config;
use think\Cookie;

/**
 * 商城订单处理模型
 */
load_trait('controller/Jump');
class ShopOrderHandle
{
    use \traits\controller\Jump;

    private $sendTerminal = '';

    // 构造函数
    public function __construct()
    {
        // 统一接收参数处理
        $this->times = getTime();
        $this->post = input('post.');
        $this->address = [];
        $this->goodsList = [];
        $this->cacheData = [];
        $this->usersData = [];
        $this->usersConfig = [];
        $this->globalConfig = [];
        $this->provider = input('provider/s', '');
        $this->sendTerminal = input('param.sendTerminal/s', 'openSource');
        $this->sendTerminal = !empty($this->sendTerminal) ? trim($this->sendTerminal) : '';
    }

    // 订单提交时基础验证
    public function orderSubmitBasicVerify($post = [], $config = [])
    {
        if (empty($post['users_id'])) $this->error('请先登录');
        if (empty($post['pay_type'])) $this->error('请选择支付方式');
        if (!empty($post['deliveryShow']) && 1 === intval($post['deliveryShow']) && (empty($post['addr_id']) || $post['addr_id'] == 'undefined')) {
            $this->error('请添加收货地址');
        }
        if ((empty($config['pay_open'])) || (empty($config['pay_wechat_open']) && empty($config['pay_balance_open']))) $this->error('暂未开启支付');
    }

    // 创建订单信息
    public function createOrderData($post = [], $address = [], $usersData = [], $globalConfig = [], $orderUseCoupon = [], $usersConfig = [])
    {
        // 参数定义
        $this->post = !empty($post) ? $post : $this->post;
        $this->address = !empty($address) ? $address : $this->address;
        $this->usersData = !empty($usersData) ? $usersData : $this->usersData;
        $this->usersConfig = !empty($usersConfig) ? $usersConfig : $this->usersConfig;
        $this->globalConfig = !empty($globalConfig) ? $globalConfig : $this->globalConfig;

        // 查询秒杀商品活动ID
        $act_id = 0;
        if (!empty($this->globalConfig['seckillActID']) && !empty($this->globalConfig['seckillGoodsID'])) {
            $act_id = intval($this->globalConfig['seckillActID']);
        }
        else if (!empty($this->globalConfig['seckillGoodsID'])) {
            $act_id = Db::name('weapp_seckill_archives')->where('goods_id', $this->globalConfig['seckillGoodsID'])->getField('act_id');
        }

        // 订单主体信息
        $orderData = [
            'order_code'         => date('Ymd') . $this->times . rand(10, 100),
            'users_id'           => $this->usersData['users_id'],
            'order_status'       => 0, // 订单未付款
            'add_time'           => $this->times,
            'payment_method'     => 0,
            'pay_time'           => 0,
            'pay_name'           => 'wechat',
            'wechat_pay_type'    => 'h5' == $this->provider ? 'WeChatInternal' : 'WeChatAppletsPay',
            'order_terminal'     => 'h5' == $this->provider ? 2 : 3,
            'pay_details'        => '',
            'order_total_amount' => $this->globalConfig['TotalAmount'],
            'order_amount'       => $this->globalConfig['PayTotalAmount'],
            'order_total_num'    => $this->globalConfig['TotalNumber'],
            'prom_type'          => $this->globalConfig['PromType'],
            'order_source'       => isset($this->post['order_source']) ? $this->post['order_source'] : 10,
            'order_source_id'    => isset($this->post['order_source_id']) ? $this->post['order_source_id'] : 0,
            'virtual_delivery'   => '',
            'admin_note'         => '',
            'user_note'          => $this->post['remark'],
            'is_seckill_order'   => $act_id,
            'use_coupon_data'    => '',
        ];

        // 使用优惠券则将优惠券信息合入订单信息
        if (!empty($orderUseCoupon)) {
            $orderData['use_id'] = !empty($orderUseCoupon['use_id']) ? intval($orderUseCoupon['use_id']) : 0;
            $orderData['coupon_id'] = !empty($orderUseCoupon['coupon_id']) ? intval($orderUseCoupon['coupon_id']) : 0;
            $orderData['coupon_price'] = !empty($orderUseCoupon['coupon_price']) ? floatval($orderUseCoupon['coupon_price']) : 0;
            $orderData['use_coupon_data'] = serialize($orderUseCoupon);
        }

        // 存在收货地址则追加合并到主表数组
        if (!empty($this->address) && !empty($this->post['deliveryShow'])) $orderData = array_merge($orderData, $this->address);

        // 余额支付
        if (2 === intval($this->post['pay_type'])) {
            $usersMoney = Db::name('users')->where('users_id', $this->post['users_id'])->getField('users_money');
            if (floatval($this->globalConfig['PayTotalAmount']) > floatval($usersMoney)) $this->error('您的余额不足，支付失败');
            $orderData['pay_name'] = 'balance';
            $orderData['wechat_pay_type'] = '';
        }
        // 抖音支付时更新订单支付类型
        else if (9 === intval($this->post['pay_type'])) {
            $orderData['pay_name'] = 'tikTokPay';
            $orderData['wechat_pay_type'] = '';
            $orderData['order_terminal'] = 9;
        }
        // 百度支付时更新订单支付类型
        else if (10 === intval($this->post['pay_type'])) {
            $orderData['pay_name'] = 'baiduPay';
            $orderData['wechat_pay_type'] = '';
            $orderData['order_terminal'] = 10;
        }

        // 返回结束
        return $orderData;
    }

    // 创建订单商品信息
    public function createOrderGoodsData($post = [], $list = [], $usersData = [], $orderData = [], $globalConfig = [])
    {
        // 参数定义
        $this->post = !empty($post) ? $post : $this->post;
        $this->list = !empty($list) ? $list : $this->list;
        $this->usersData = !empty($usersData) ? $usersData : $this->usersData;
        $this->orderData = !empty($orderData) ? $orderData : $this->orderData;
        $this->globalConfig = !empty($globalConfig) ? $globalConfig : $this->globalConfig;

        // 订单商品信息
        $cartIds = $upSpecValue = $orderGoods = [];
        foreach ($this->list as $key => $value) {
            // 规格及属性
            $paramData = [
                // 商品规格
                'spec_value' => model('ShopPublicHandle')->getGoodsSpecList($value),
                // 商品属性
                'attr_value' => model('ShopPublicHandle')->getGoodsAttrList($value),
                // 规格值ID
                'value_id' => !empty($value['value_id']) ? $value['value_id'] : '',
                // 商品规格值ID
                'spec_value_id' => !empty($value['spec_value_id']) ? $value['spec_value_id'] : '',
                // 秒杀商品ID
                'goods_id' => !empty($this->globalConfig['seckillGoodsID']) ? $this->globalConfig['seckillGoodsID'] : 0,
                // 商品分类ID
                'goods_stypeid' => !empty($value['stypeid']) ? $value['stypeid'] : '',
            ];
            // 订单副表添加数组
            $orderGoods[] = [
                'order_id'      => $this->orderData['order_id'],
                'users_id'      => $this->post['users_id'],
                'product_id'    => $value['aid'],
                'product_name'  => $value['title'],
                'num'           => $value['product_num'],
                'data'          => serialize($paramData),
                'product_price' => $value['users_price'],
                'prom_type'     => $value['prom_type'],
                'litpic'        => $value['litpic'],
                'add_time'      => $this->times,
            ];

            // 处理购物车ID
            if (empty($this->globalConfig['submit_order_type']) && !empty($value['cart_id'])) array_push($cartIds, $value['cart_id']);

            // 商品库存处理
            $upSpecValue[] = [
                'aid' => $value['aid'],
                'goods_id' => $this->globalConfig['seckillGoodsID'],
                'value_id' => $value['value_id'],
                'quantity' => $value['product_num'],
                'spec_value_id' => $value['spec_value_id'],
                'order_source'  => isset($this->post['order_source']) ? $this->post['order_source'] : 10,
                'order_source_id' => isset($this->post['order_source_id']) ? $this->post['order_source_id'] : 0,
            ];
        }

        // 返回结束
        return [$cartIds, $orderGoods, $upSpecValue];
    }

    // 订单创建添加成功后续处理
    public function createOrderHandle($cartIds = [], $orderData = [], $upSpecValue = [])
    {
        // 清理购物车中已下单的ID
        if (!empty($cartIds)) Db::name('shop_cart')->where('cart_id', 'IN', $cartIds)->delete(true);

        // 商品库存、销量处理
        if (!empty($upSpecValue)) $this->handleOrderGoodsStock($upSpecValue);

        // 添加订单操作记录
        if (!empty($orderData['order_id']) && !empty($orderData['users_id'])) AddOrderAction($orderData['order_id'], $orderData['users_id']);
    }

    // 扣除商品库存
    public function handleOrderGoodsStock($upSpecValue = [])
    {
        if (!empty($upSpecValue)) {
            // 库存处理
            $systemGoods = $systemGoodsSpec = [];
            $seckillGoods = $seckillGoodsSpec = [];
            foreach ($upSpecValue as $key => $value) {
                // 多规格商品处理
                if (!empty($value['value_id'])) {
                    // 秒杀商品
                    if (!empty($value['goods_id'])) {
                        // 秒杀商品库存
                        $seckillGoods[] = [
                            'goods_id' => $value['goods_id'],
                            'buy_count' => Db::raw('buy_count+' . ($value['quantity'])),
                            'seckill_stock' => Db::raw('seckill_stock-' . ($value['quantity'])),
                            'update_time' => getTime(),
                        ];

                        // 秒杀商品规格库存
                        $seckillGoodsSpec[] = [
                            'value_id' => $value['value_id'],
                            'seckill_stock' => Db::raw('seckill_stock-' . ($value['quantity'])),
                            'seckill_sales_num' => Db::raw('seckill_sales_num+' . ($value['quantity'])),
                            'update_time' => getTime(),
                        ];

                        // 系统商品规格库存
                        $where = [
                            'aid' => $value['aid'],
                            'spec_value_id' => $value['spec_value_id']
                        ];
                        $update = [
                            'spec_stock' => Db::raw('spec_stock-' . ($value['quantity'])),
                            'spec_sales_num' => Db::raw('spec_sales_num+' . ($value['quantity'])),
                            'update_time' => getTime(),
                        ];
                        Db::name('product_spec_value')->where($where)->update($update);
                    }
                    // 系统商品
                    else {
                        // 系统商品规格库存
                        $systemGoodsSpec[] = [
                            'value_id' => $value['value_id'],
                            'spec_stock' => Db::raw('spec_stock-' . ($value['quantity'])),
                            'spec_sales_num' => Db::raw('spec_sales_num+' . ($value['quantity'])),
                            'update_time' => getTime(),
                        ];
                    }

                    // 系统商品库存
                    $systemGoods[] = [
                        'aid' => $value['aid'],
                        'stock_count' => Db::raw('stock_count-' . ($value['quantity'])),
                        'sales_num'   => Db::raw('sales_num+' . ($value['quantity'])),
                        'sales_all'   => Db::raw('sales_all+' . ($value['quantity'])),
                        'update_time' => getTime(),
                    ];
                }
                // 单规格商品处理
                else {
                    // 秒杀商品
                    if (!empty($value['goods_id'])) {
                        // 秒杀商品库存
                        $seckillGoods[] = [
                            'goods_id' => $value['goods_id'],
                            'stock' => Db::raw('stock-' . ($value['quantity'])),
                            'buy_count' => Db::raw('buy_count+' . ($value['quantity'])),
                            'seckill_stock' => Db::raw('seckill_stock-' . ($value['quantity'])),
                            'update_time' => getTime(),
                        ];
                    }

                    // 系统商品库存
                    $systemGoods[] = [
                        'aid' => $value['aid'],
                        'stock_count' => Db::raw('stock_count-' . ($value['quantity'])),
                        'sales_num'   => Db::raw('sales_num+' . ($value['quantity'])),
                        'sales_all'   => Db::raw('sales_all+' . ($value['quantity'])),
                        'update_time' => getTime(),
                    ];
                }
            }

            // 更新商品库存销量
            if (!empty($systemGoods)) {
                $archivesModel = new \app\user\model\Archives();
                $archivesModel->saveAll($systemGoods);
            }

            // 更新规格库存销量
            if (!empty($systemGoodsSpec)) {
                $productSpecValueModel = new \app\user\model\ProductSpecValue();
                $productSpecValueModel->saveAll($systemGoodsSpec);
            }

            // 更新商品库存销量
            if (!empty($seckillGoods)) {
                $archivesModel = new \app\user\model\WeappSeckillArchives();
                $archivesModel->saveAll($seckillGoods);
            }

            // 更新规格库存销量
            if (!empty($seckillGoodsSpec)) {
                $productSpecValueModel = new \app\user\model\WeappSeckillProductSpecValue();
                $productSpecValueModel->saveAll($seckillGoodsSpec);
            }
        }
    }

}